<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>《程序员修炼之道：从小工到专家》读书笔记 | Brennan&#39;s blog</title>
    <meta name="generator" content="VuePress 1.9.5">
    <link rel="icon" href="/brennan-wu-blog/img/favicon.ico">
    <meta name="description" content="web前端技术博客,专注web前端学习与总结。JavaScript,js,ES6,TypeScript,vue,React,python,css3,html5,Node,git,github等技术文章。">
    <meta name="keywords" content="前端博客,个人技术博客,前端,前端开发,前端框架,web前端,前端面试题,技术文档,学习,面试,JavaScript,js,ES6,TypeScript,vue,python,css3,html5,Node,git,github,markdown">
    <meta name="baidu-site-verification" content="7F55weZDDc">
    <meta name="theme-color" content="#11a8cd">
    
    <link rel="preload" href="/brennan-wu-blog/assets/css/0.styles.6d0ebdc8.css" as="style"><link rel="preload" href="/brennan-wu-blog/assets/js/app.422e2e24.js" as="script"><link rel="preload" href="/brennan-wu-blog/assets/js/2.372f0770.js" as="script"><link rel="preload" href="/brennan-wu-blog/assets/js/3.22a0f36b.js" as="script"><link rel="preload" href="/brennan-wu-blog/assets/js/28.d5292c46.js" as="script"><link rel="prefetch" href="/brennan-wu-blog/assets/js/10.9b0e0932.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/11.389398e0.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/12.c046ebcf.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/13.ebdfb480.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/14.f75b9d1c.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/15.d20a3fd0.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/16.3816d4a5.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/17.bbbea7a6.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/18.214ef1b5.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/19.0363e8ba.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/20.a38f522d.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/21.6b18ffad.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/22.5c3876be.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/23.dcf195c4.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/24.7e75542f.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/25.9d5b9250.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/26.040652ab.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/27.b3041988.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/29.7ced233f.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/30.4856fc6c.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/31.0e508fe6.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/32.54efed0e.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/33.89aebe9c.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/34.124399ef.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/35.b1225438.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/36.8909f7ca.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/37.8321b812.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/38.4b637941.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/39.119a3f2c.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/4.28226b98.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/40.9624480f.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/41.df28c0a9.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/42.33d89136.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/43.04ab01ff.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/44.867b4caf.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/45.1337d2e2.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/5.e01b5955.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/6.4fe91b18.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/7.c836dcbd.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/8.85621850.js"><link rel="prefetch" href="/brennan-wu-blog/assets/js/9.5c2abfd9.js">
    <link rel="stylesheet" href="/brennan-wu-blog/assets/css/0.styles.6d0ebdc8.css">
  </head>
  <body class="theme-mode-light">
    <div id="app" data-server-rendered="true"><div class="theme-container sidebar-open have-rightmenu"><header class="navbar blur"><div title="目录" class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/brennan-wu-blog/" class="home-link router-link-active"><img src="/brennan-wu-blog/img/logo.png" alt="Brennan's blog" class="logo"> <span class="site-name can-hide">Brennan's blog</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/brennan-wu-blog/" class="nav-link">首页</a></div><div class="nav-item"><a href="/brennan-wu-blog/study/" class="nav-link">学习笔记</a></div><div class="nav-item"><a href="/brennan-wu-blog/grow/" class="nav-link">成长笔记</a></div><div class="nav-item"><a href="/brennan-wu-blog/read/" class="nav-link">读书笔记</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="收藏导航" class="dropdown-title"><a href="/brennan-wu-blog/collection/" class="link-title">收藏导航</a> <span class="title" style="display:none;">收藏导航</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/brennan-wu-blog/pages/527bc4/" class="nav-link">我的导航</a></li><li class="dropdown-item"><!----> <a href="/brennan-wu-blog/pages/c8836a/" class="nav-link">我的收藏</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="索引" class="dropdown-title"><a href="/brennan-wu-blog/archives/" class="link-title">索引</a> <span class="title" style="display:none;">索引</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/brennan-wu-blog/categories/" class="nav-link">分类</a></li><li class="dropdown-item"><!----> <a href="/brennan-wu-blog/tags/" class="nav-link">标签</a></li><li class="dropdown-item"><!----> <a href="/brennan-wu-blog/archives/" class="nav-link">归档</a></li></ul></div></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar-hover-trigger"></div> <aside class="sidebar" style="display:none;"><div class="blogger"><img src="/brennan-wu-blog/img/logo.png"> <div class="blogger-info"><h3>Brennan Wu</h3> <span>过度忙碌使你落后，有空别忘了给自己充电!</span></div></div> <nav class="nav-links"><div class="nav-item"><a href="/brennan-wu-blog/" class="nav-link">首页</a></div><div class="nav-item"><a href="/brennan-wu-blog/study/" class="nav-link">学习笔记</a></div><div class="nav-item"><a href="/brennan-wu-blog/grow/" class="nav-link">成长笔记</a></div><div class="nav-item"><a href="/brennan-wu-blog/read/" class="nav-link">读书笔记</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="收藏导航" class="dropdown-title"><a href="/brennan-wu-blog/collection/" class="link-title">收藏导航</a> <span class="title" style="display:none;">收藏导航</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/brennan-wu-blog/pages/527bc4/" class="nav-link">我的导航</a></li><li class="dropdown-item"><!----> <a href="/brennan-wu-blog/pages/c8836a/" class="nav-link">我的收藏</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="索引" class="dropdown-title"><a href="/brennan-wu-blog/archives/" class="link-title">索引</a> <span class="title" style="display:none;">索引</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/brennan-wu-blog/categories/" class="nav-link">分类</a></li><li class="dropdown-item"><!----> <a href="/brennan-wu-blog/tags/" class="nav-link">标签</a></li><li class="dropdown-item"><!----> <a href="/brennan-wu-blog/archives/" class="nav-link">归档</a></li></ul></div></div> <!----></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>个人成长</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>专业技术</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/brennan-wu-blog/pages/b08d0e/" class="sidebar-link">《软技能-代码之外的生存指南》读书笔记</a></li><li><a href="/brennan-wu-blog/pages/2ffcfe/" class="sidebar-link">《技术领导力：程序员如何才能带团队》读书笔记</a></li><li><a href="/brennan-wu-blog/pages/3b0243/" aria-current="page" class="active sidebar-link">《程序员修炼之道：从小工到专家》读书笔记</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level2"><a href="/brennan-wu-blog/pages/3b0243/#第1章-注重实效的哲学" class="sidebar-link">第1章 注重实效的哲学</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#我的源码让猫吃了" class="sidebar-link">我的源码让猫吃了</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#软件的墒" class="sidebar-link">软件的墒</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#石头汤与煮青蛙" class="sidebar-link">石头汤与煮青蛙</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#足够好的软件" class="sidebar-link">足够好的软件</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#你的知识资产" class="sidebar-link">你的知识资产</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#交流" class="sidebar-link">交流</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/brennan-wu-blog/pages/3b0243/#第2章-注重实效的途径" class="sidebar-link">第2章 注重实效的途径</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#重复的危害" class="sidebar-link">重复的危害</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#正交性" class="sidebar-link">正交性</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#曳光弹" class="sidebar-link">曳光弹</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#原型" class="sidebar-link">原型</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#估算" class="sidebar-link">估算</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/brennan-wu-blog/pages/3b0243/#第3章-基本工具" class="sidebar-link">第3章 基本工具</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#shell游戏" class="sidebar-link">shell游戏</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#源码控制" class="sidebar-link">源码控制</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#调试" class="sidebar-link">调试</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/brennan-wu-blog/pages/3b0243/#第4章-注重实效的偏执" class="sidebar-link">第4章 注重实效的偏执</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#按合约设计" class="sidebar-link">按合约设计</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#死程序不说谎" class="sidebar-link">死程序不说谎</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/brennan-wu-blog/pages/3b0243/#第5章-弯曲或折断" class="sidebar-link">第5章 弯曲或折断</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#解耦与得墨忒耳法则" class="sidebar-link">解耦与得墨忒耳法则</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#时间耦合" class="sidebar-link">时间耦合</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/brennan-wu-blog/pages/3b0243/#第6章-当你编码时" class="sidebar-link">第6章 当你编码时</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#靠巧合编程" class="sidebar-link">靠巧合编程</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#如何深思熟虑地编程" class="sidebar-link">如何深思熟虑地编程</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#重构" class="sidebar-link">重构</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/brennan-wu-blog/pages/3b0243/#第7章-在项目开始之前" class="sidebar-link">第7章 在项目开始之前</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#需求之坑" class="sidebar-link">需求之坑</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#等你准备好" class="sidebar-link">等你准备好</a></li></ul></li><li class="sidebar-sub-header level2"><a href="/brennan-wu-blog/pages/3b0243/#第8章-注重实效的项目" class="sidebar-link">第8章 注重实效的项目</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#注重实效的团队" class="sidebar-link">注重实效的团队</a></li><li class="sidebar-sub-header level3"><a href="/brennan-wu-blog/pages/3b0243/#极大的期望" class="sidebar-link">极大的期望</a></li></ul></li></ul></li><li><a href="/brennan-wu-blog/pages/c002a8/" class="sidebar-link">《从技术走向管理：李元芳履职记》读书笔记</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>教育学习</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <div><main class="page"><div class="theme-vdoing-wrapper "><div class="articleInfo-wrap" data-v-5712e8f9><div class="articleInfo" data-v-5712e8f9><ul class="breadcrumbs" data-v-5712e8f9><li data-v-5712e8f9><a href="/brennan-wu-blog/" title="首页" class="iconfont icon-home router-link-active" data-v-5712e8f9></a></li> <li data-v-5712e8f9><a href="/brennan-wu-blog/read/#读书笔记" data-v-5712e8f9>读书笔记</a></li><li data-v-5712e8f9><a href="/brennan-wu-blog/read/#专业技术" data-v-5712e8f9>专业技术</a></li></ul> <div class="info" data-v-5712e8f9><div title="作者" class="author iconfont icon-geren" data-v-5712e8f9><a href="https://github.com/wyd112821" target="_blank" title="作者" class="beLink" data-v-5712e8f9>Brennan Wu</a></div> <div title="创建时间" class="date iconfont icon-rili" data-v-5712e8f9><a href="javascript:;" data-v-5712e8f9>2022-11-28</a></div> <!----></div></div></div> <!----> <div class="content-wrapper"><div class="right-menu-wrapper"><div class="right-menu-margin"><div class="right-menu-title">目录</div> <div class="right-menu-content"></div></div></div> <h1><img src="">《程序员修炼之道：从小工到专家》读书笔记<!----></h1> <!----> <div class="theme-vdoing-content content__default"><h1 id="程序员修炼之道-从小工到专家"><a href="#程序员修炼之道-从小工到专家" class="header-anchor">#</a> 程序员修炼之道：从小工到专家</h1> <p><img src="https://cdn.staticaly.com/gh/wyd112821/Blogger@master/static_files/img/WX20221128-104801@2x.3aid2t2r9e40.webp" alt="WX20221128-104801@2x"></p> <h2 id="第1章-注重实效的哲学"><a href="#第1章-注重实效的哲学" class="header-anchor">#</a> 第1章 注重实效的哲学</h2> <h3 id="我的源码让猫吃了"><a href="#我的源码让猫吃了" class="header-anchor">#</a> 我的源码让猫吃了</h3> <p>注重实效的程序员对他到职业生涯负责，并且不害怕承认无知和错误。</p> <p>承若确保某件事正确完成，但你不一定能直接控制事情的每一个方面，你必须分析风险是否超出了你的控制，必须基于你自己的道德准则和判断来做出决定。</p> <p>当你犯错误时、或是判断失误时，诚实的承认它，并设法给出各种选择或解决方案，而非寻找借口。</p> <h3 id="软件的墒"><a href="#软件的墒" class="header-anchor">#</a> 软件的墒</h3> <p>熵是一个来自物理学的概念，指的是某个系统中的“无序”的总量。当软件中的无序增长时，程序员们称之为“软件腐烂”。</p> <p>不要留着“破窗户”（低劣的设计、错误决策、或是糟糕的代码）不修。发现一个就修一个。如果没有足够的时间进行适当的修理，你可以把出问题的代码放入注释，或是显示“未实现”消息，或是用虚设的数据加以替代。采取某种行动防止进一步的损坏，并说明情势处在你的控制之下。</p> <p>如果你所在团队和项目的代码十分漂亮——编写整洁、设计良好，并且很优雅——你就很可能会格外注意不去把它弄脏。即使有最后期限、发布日期、会展演示等等，你也不会想成为第一个弄脏东西的人。</p> <h3 id="石头汤与煮青蛙"><a href="#石头汤与煮青蛙" class="header-anchor">#</a> 石头汤与煮青蛙</h3> <p>做变化的催化剂。设计出你可以合理要求的东西，好好开发它。一旦完成，就拿给大家看，让他们大吃一惊。然后说：“要是我们增加……可能就会更好。”等着他们开始要你增加你本来就想要的功能。人们发现，参与正在发生的成功要更容易。让他们瞥见未来，你就能让他们聚集在你周围。这是协作的成果。最后每个人都是赢家。</p> <p>我们都看见过这样的症状。项目慢慢地、不可改变地完全失去控制。大多数软件灾难都是从微不足道的小事情开始的，大多数项目的拖延都是一天一天发生的。系统一个特性一个特性地偏离其规范，一个又一个的补丁被打到某段代码上，直到最初的代码一点没有留下。常常是小事情的累积破坏了士气和团队。</p> <p>留心大图景。要持续不断地观察周围发生的事情，而不只是你自己在做的事情。</p> <h3 id="足够好的软件"><a href="#足够好的软件" class="header-anchor">#</a> 足够好的软件</h3> <p>你可以训练你自己，编写出足够好的软件——对你的用户、对未来的维护者、对你自己内心的安宁来说足够好。你会发现，你变得更多产，而你的用户也会更加高兴。你也许还会发现，因为“孵化期”更短，你的程序实际上更好了。</p> <p>“足够好”并非意味着不整洁或制作糟糕的代码。所有系统都必须满足其用户的需求，才能取得成功。我们只是在宣扬，应该给用户以机会，让他们参与决定你所制作的东西何时已足够好。</p> <p>不要因为过度修饰和过于求精而毁损完好的程序。继续前进，让你的代码凭着自己的质量站立一会儿。它也许不完美，但不用担心：它不可能完美。</p> <h3 id="你的知识资产"><a href="#你的知识资产" class="header-anchor">#</a> 你的知识资产</h3> <p>你的知识和经验是你最重要的职业财富。遗憾的是，它们是有时效的资产。</p> <p>要想在职业生涯中获得成功，你必须运用一些金融管理的指导方针管理你的知识资产。</p> <ul><li><strong>定期投资</strong>——你必须定期为你的知识资产投资。即使投资量很小，习惯自身也和总量一样重要。</li> <li><strong>多元化</strong>——你掌握的技术越多，你就越能更好地进行调整，赶上变化。</li> <li><strong>管理风险</strong>——不要把你所有的技术鸡蛋放在一个篮子里。要平衡自己的知识资产。</li> <li><strong>低买高卖</strong>——在新兴的技术流行之前学习它可能有风险，但相对未来可能会有巨大的回报。</li> <li><strong>重新评估和平衡</strong>——应周期性地重新评估和平衡自己的知识资产。批判地思考你读到的和听到的，确保你的资产中的知识是准确的，有实效的。</li></ul> <h3 id="交流"><a href="#交流" class="header-anchor">#</a> 交流</h3> <ul><li><strong>知道你想要说什么</strong>——提前规划你想要说的东西，提炼它们，写出大纲。</li> <li><strong>了解你的听众</strong>——需要了解你的听众的需要、兴趣、能力。针对不同的人进行适当的修正，你将让他们都为你交流内容感到兴奋。</li> <li><strong>选择时机</strong>——为了了解你的听众需要听到什么，你需要弄清楚他们的“轻重缓急”是什么，要让你所说的适得其时，在内容上切实相关。</li> <li><strong>选择风格</strong>——调整你的交流风格，让其适应你的听众。如果有疑问，就询问对方，这样的反馈也是交流的一种形式。</li> <li><strong>让文档美观</strong>——你的主意很重要，它们应该以美观的方式传递给你的听众。</li> <li><strong>让听众参与</strong>——让你的听众早早的参与内容的生成过程，获取他们的反馈，并汲取他们的智慧，这将建立起一种良好的工作关系。</li> <li><strong>做倾听者</strong>——想让大家听你说话，你必须要听他们说话，鼓励大家通过提问来交谈。</li> <li><strong>回复他人</strong>——别人提问时，要做到随时回应，避免经常性的忘记回复。</li></ul> <h2 id="第2章-注重实效的途径"><a href="#第2章-注重实效的途径" class="header-anchor">#</a> 第2章 注重实效的途径</h2> <h3 id="重复的危害"><a href="#重复的危害" class="header-anchor">#</a> 重复的危害</h3> <p>可靠地开发软件、并让我们的开发更易于理解和维护的唯一途径，是遵循我们称之为DRY（Don't Repeat Yourself）的原则：<strong>系统中的每一项知识都必须具有单一、无歧义、权威的表示。</strong></p> <p>重复是怎样发生的？可归入下列范畴：</p> <ul><li><strong>强加的重复</strong>——开发者觉得他们无可选择——环境似乎要求重复。</li> <li><strong>无意的重复</strong>——开发者没有意识到他们在重复信息。</li> <li><strong>无耐性的重复</strong>——开发者偷懒，他们重复，因为那样似乎更容易。</li> <li><strong>开发者之间的重复</strong>——同一团队（或不同团队）的几个人重复了同样的信息。</li></ul> <h3 id="正交性"><a href="#正交性" class="header-anchor">#</a> 正交性</h3> <p><strong>什么是正交性</strong>——表示某种不相依赖性或是解耦性。如果两个或更多事物中的一个发生变化，不会影响其他事物，这些事物就是正交的。</p> <p><strong>正交的好处</strong></p> <ul><li><strong>提高生产率</strong>——改动得以局部化，所以开发时间和测试时间得以降低。正交的途径能够促进复用。</li> <li><strong>降低风险</strong>——有问题的代码区域被隔离开来，所得系统更健壮。</li></ul> <p><strong>工作中应用正交原则的几种方式</strong></p> <ul><li><strong>项目团队</strong></li></ul> <p>如果团队的组织有许多重叠，各个成员就会对责任感到困惑。每一次改动都需要整个团队开一次会，因为他们中的任何一个人都可能受到影响。</p> <p>怎样把团队划分为责任得到了良好定义的小组，并使重叠降至最低呢？从使基础设施与应用分离开始。每个主要的基础设施组件（数据库、通信接口、中间件层，等等）有自己的子团队。如果应用功能的划分显而易见，那就照此划分。然后我们考察我们现有的（或计划有的）人员，并对分组进行相应的调整。</p> <p>人数越多，团队的正交性就越差。显然，正交的团队效率也更高（尽管如此，我们也鼓励子团队不断地相互交流）。</p> <ul><li><strong>设计</strong></li></ul> <p>大多数开发者都熟知需要设计正交的系统。</p> <p>系统应该由一组相互协作的模块组成，每个模块都实现不依赖于其他模块的功能。有时，这些组件被组织为多个层次，每层提供一级抽象。这种分层的途径是设计正交系统的强大方式。因为每层都只使用在其下面的层次提供的抽象，在改动底层实现、而又不影响其他代码方面，你拥有极大的灵活性。分层也降低了模块间依赖关系失控的风险。</p> <ul><li><strong>工具箱与库</strong></li></ul> <p>在你引入第三方工具箱和库时，要注意保持系统的正交性。要明智地选择技术。</p> <p>在引入某个工具箱时（甚或是来自你们团队其他成员的库），问问你自己，它是否会迫使你对代码进行不必要的改动。</p> <ul><li><strong>编码</strong></li></ul> <p>每次你编写代码，都有降低应用正交性的风险。</p> <p>可以将若干技术用于维持正交性：</p> <ol><li>让你的代码保持解耦</li> <li>避免使用全局数据</li> <li>避免编写相似的函数</li></ol> <p>养成不断地批判对待自己的代码的习惯。寻找任何重新进行组织、以改善其结构和正交性的机会。这个过程叫做重构</p> <ul><li><strong>测试</strong></li></ul> <p>正交地设计和实现的系统也更易于测试，因为系统的各组件间的交互是形式化的和有限的，更多的系统测试可以在单个的模块级进行。</p> <p>我们建议让每个模块都拥有自己的、内建在代码中的单元测试，并让这些测试作为常规构建过程的一部分自动运行，构建单元测试本身是对正交性的一项有趣测试。</p> <p><strong>认同正交性</strong></p> <p>运用DRY原则，你是在寻求使系统中的重复降至最小；运用正交性原则，你可降低系统的各组件间的相互依赖。</p> <p>如果你紧密结合DRY原则、运用正交性原则，你将会发现你开发的系统会变得更为灵活、更易于理解、并且更易于调试、测试和维护。</p> <h3 id="曳光弹"><a href="#曳光弹" class="header-anchor">#</a> 曳光弹</h3> <p>曳光弹行之有效，是因为它们与真正的子弹在相同的环境、相同的约束下工作。它们快速飞向目标，所以枪手可以得到即时的反馈。同时，从实践的角度看，这样的解决方案也更便宜。</p> <p>为了在代码中获得同样的效果，我们要找到某种东西，让我们能快速、直观和可重复地从需求出发，满足最终系统的某个方面要求。</p> <p>曳光代码并非用过就扔的代码：你编写它，是为了保留它。它含有任何一段产品代码都拥有的完整的错误检查、结构、文档、以及自查。它只不过功能不全而已。但是，一旦你在系统的各组件间实现了端到端的连接，你就可以检查你离目标还有多远，并在必要的情况下进行调整。一旦你完全瞄准，增加功能将是一件容易的事情。</p> <p>曳光开发与项目永不会结束的理念是一致的：总有改动需要完成，总有功能需要增加。这是一个渐进的过程。</p> <p>曳光代码方法有许多优点：</p> <ul><li><p><strong>用户能够及早看到能工作的东西</strong>——如果你成功地就你在做的事情与用户进行了交流，用户就会知道他们看到的是还未完成的东西。他们不会因为缺少功能而失望；他们将因为看到了系统的某种可见的进展而欣喜陶醉。他们还会随着项目的进展做出贡献，增加他们的“买入”。同样是这些用户，他们很可能也会告诉你，每一轮“射击”距离目标有多接近。</p></li> <li><p><strong>开发者构建了一个他们能在其中工作的结构</strong>——如果你已经找出应用的所有端到端的交互，并把它们体现在代码里，你的团队就无须再无中生有。这让每个人都变得更有生产力，同时又促进了一致性。</p></li> <li><p><strong>你有了一个集成平台</strong>——随着系统端到端地连接起来，你拥有了一个环境，一旦新的代码段通过了单元测试，你就可以将其加入该环境中。你将每天进行集成，而不是尝试进行大爆炸式的集成。每一个新改动的影响都更为显而易见，而交互也更为有限，于是调试和测试将变得更快、更准确。</p></li> <li><p><strong>你有了可用于演示的东西</strong>——有了曳光代码，你总有东西可以拿给他们看。</p></li> <li><p><strong>你将更能够感觉到工作进展</strong>——在曳光代码开发中，开发者一个一个地处理用例。做完一个，再做下一个。评测性能、并向用户演示你的进展，变得容易了许多。</p></li></ul> <p><strong>曳光弹并非总能击中目标</strong></p> <p>曳光弹告诉你击中的是什么。那不一定总是目标。于是你调整准星，直到完全击中目标为止。这正是要点所在。曳光代码也是如此。</p> <p>小段代码的惯性也小——要改变它更容易、更迅速。你能够搜集关于你的应用的反馈，而且与其他任何方法相比，你能够花费较少代价、更为迅速地生成新的、更为准确的版本。同时，因为每个主要的应用组件都已表现在你的曳光代码中，用户可以确信，他们所看到的东西具有现实基础，不仅仅是纸上的规范。</p> <p><strong>曳光代码 vs.原型制作</strong></p> <p>原型制作生成用过就扔的代码。曳光代码虽然简约，但却是完整的，并且构成了最终系统的骨架的一部分。</p> <p>你需要知道应用怎样结合成一个整体。你想要向用户演示，实际的交互是怎样工作的，同时你还想要给出一个架构骨架，开发者可以在其上增加代码。在这样的情况下，你可以构造一段曳光代码，其中含有一个极其简单的算法实现和一个简单、但却能工作的用户界面。一旦你把应用中的所有组件都组合在一起，你就拥有了一个可以向你的用户和开发者演示的框架。接下来的时间里，你给这个框架增加新功能，完成预留了接口的例程。但框架仍保持完整，而你也知道，系统将会继续按照你第一次的曳光代码完成时的方式工作。</p> <h3 id="原型"><a href="#原型" class="header-anchor">#</a> 原型</h3> <p>用户界面的原型则可以是白板上的图形、或是用绘图程序或界面构建器绘制的无功能的模型。</p> <p>原型的设计目的就是回答一些问题，所以与投入使用的产品应用相比，它们的开发要便宜得多、快捷得多。</p> <p><strong>应制作原型的事物:</strong></p> <ul><li>架构</li> <li>已有系统中的新功能</li> <li>外部数据的结构或内容</li> <li>第三方工具或组件</li> <li>性能问题</li> <li>用户界面设计</li></ul> <p>原型制作是一种学习经验。其价值并不在于所产生的代码，而在于所学到的经验教训。那才是原型制作的要点所在。</p> <p><strong>怎样使用原型</strong></p> <p><strong>正确性</strong>——你也许可以在适当的地方使用虚设的数据。</p> <p><strong>完整性</strong>——原型也许只能在非常有限的意义上工作，也许只有一项预先选择的输入数据和一个菜单项。</p> <p><strong>健壮性</strong>——错误检查很可能不完整，或是完全没有。</p> <p><strong>风格</strong>——原型代码可能没有多少注释或文档。</p> <p><strong>制作架构原型</strong></p> <p>许多原型被构造出来，是要为在考虑之下的整个系统建模。</p> <p>你寻求的是了解系统怎样结合成为一个整体，并推迟考虑细节。下面是一些你可以在架构原型中寻求解答的具体问题：</p> <ul><li>主要组件的责任是否得到了良好定义？是否适当？</li> <li>主要组件间的协作是否得到了良好定义？</li> <li>耦合是否得以最小化？</li> <li>你能否确定重复的潜在来源？</li> <li>接口定义和各项约束是否可接受？</li> <li>每个模块在执行过程中是否能访问到其所需的数据？是否能在需要时进行访问？</li></ul> <p><strong>怎样“不”使用原型</strong></p> <p>如果你觉得在你所在的环境或文化中，原型代码的目的很有可能被误解，你也许最好还是采用曳光弹方法。你最后将得到一个坚实的框架，为将来的开发奠定基础。</p> <p>适当地使用原型，可以帮助你在开发周期的早期确定和改正潜在的问题点——在此时改正错误既便宜、又容易——从而为你节省大量时间、金钱，并大大减轻你遭受的痛苦和折磨。</p> <h3 id="估算"><a href="#估算" class="header-anchor">#</a> 估算</h3> <p>通过学习估算，并将此技能发展到你对事物的数量级有直觉的程度，你就能展现出一种魔法般的能力，确定它们的可行性。</p> <p><strong>估算项目进度</strong></p> <p>为项目确定进度表的唯一途径常常是在相同的项目上获取经验。如果你实行增量开发、重复下面的步骤：</p> <ol><li>理解需求</li> <li>拆分需求，精确的维度可能是接口或者某个子模块</li> <li>考虑接口或者模块交互</li> <li>给出最终时间</li></ol> <p>一开始，你对需要多少次迭代、或是需要多少时间，也许只有模糊的概念。除非你在开发与前一个应用类似的应用，拥有同样的团队和同样的技术，否则，你就只不过是在猜想。</p> <p><strong>在被要求进行估算时说什么</strong></p> <p>不要太急于下结论，如果真的是要的非常非常急，证明他不是真正的急，真正的急是在开始时刻就要计算好时间。</p> <p>另外不要对开发保持很乐观的估计，一般感觉还是工时*1.25或者1.5更为稳妥，很多时候，我们需要一些时间来缓冲资源不到位引起的问题。</p> <p>另外承诺是严肃的，一旦给出了承诺，无论采用何种方式，何种技术，始终是要保证在确定时间点来进行交付，这是对自己负责，也是对他人负责。</p> <h2 id="第3章-基本工具"><a href="#第3章-基本工具" class="header-anchor">#</a> 第3章 基本工具</h2> <h3 id="shell游戏"><a href="#shell游戏" class="header-anchor">#</a> shell游戏</h3> <p><strong>注重实效的程序员</strong>并非只是剪切代码、或是开发对象模型、或是撰写文档、或是使构建过程自动化——所有这些事情我们全都要做。</p> <p>作为<strong>注重实效的程序员</strong>，你不断地想要执行特别的操作——GUI可能不支持的操作。当你想要快速地组合一些命令，以完成一次查询或某种其他的任务时，命令行要更为适宜。</p> <p>shell命令可能很晦涩，或是太简略，但却很强大，也很简练。同时，因为shell命令可被组合进脚本文件中，你可以构建命令序列，使你常做的事情自动化。</p> <p>投入一些精力去熟悉你的shell，事情很快就会变得清楚起来。多使用你的命令shell，你会惊讶它能使你的生产率得到怎样的提高。</p> <h3 id="源码控制"><a href="#源码控制" class="header-anchor">#</a> 源码控制</h3> <p>使用源码控制系统的诸多好处之一：它是一个巨大的UNDO键——一个项目级的时间机器，追踪你在源码和文档中做出的每一项变动，并使你总能够返回你的软件的前一版本。</p> <p>好的源码控制习惯在协同开发点过程中尤为重要，一定要做好源码的统一和协调。</p> <p>把整个项目置于源码控制系统的保护之下具有一项很大的、隐蔽的好处：你可以进行自动的和可重复的产品构建。</p> <h3 id="调试"><a href="#调试" class="header-anchor">#</a> 调试</h3> <p>软件缺陷以各种各样的方式表现自己，从被误解的需求到编码错误。</p> <p>没有人能写出完美的软件，所以调试肯定要占用大量时间。</p> <p><strong>调试的心理学</strong></p> <p>调试就是解决问题，要据此发起进攻。</p> <p>发现了他人的bug之后，你应该专注于修正问题，而不是发出指责。</p> <p><strong>调试的思维方式</strong></p> <p>在你开始调试之前，记住调试的第一准则：<strong>不要恐慌</strong></p> <p>非常重要的事情是，要后退一步，实际思考什么可能造成你认为表征了bug的那些症状。</p> <p>要总是设法找出问题的根源，而不只是问题的特定表现。</p> <p><strong>从何处开始</strong></p> <p>在设法解决任何问题时，你需要搜集所有的相关数据；</p> <p>实际上你可能需要观察报告bug的用户的操作，以获取足够程度的细节；</p> <p>你必须既强硬地测试边界条件，又测试现实中的最终用户的使用模式，你需要系统地进行这样的测试。</p> <p><strong>橡皮鸭</strong></p> <p>找到问题的原因的一种非常简单、却又特别有用的技术是向别人解释它。</p> <p>这听起来很简单，但在向他人解释问题时，你必须明确地陈述那些你在自己检查代码时想当然的事情。因为必须详细描述这些假定中的一部分，你可能会突然获得对问题的新洞见。</p> <p><strong>不要假定，要证明</strong></p> <p>当你遇到让人吃惊的bug时，除了只是修正它而外，你还需要确定先前为什么没有找出这个故障。</p> <p>如果bug是某人的错误假定的结果，与整个团队一起讨论这个问题。如果一个人有误解，那么许多人可能也有。</p> <h2 id="第4章-注重实效的偏执"><a href="#第4章-注重实效的偏执" class="header-anchor">#</a> 第4章 注重实效的偏执</h2> <h3 id="按合约设计"><a href="#按合约设计" class="header-anchor">#</a> 按合约设计</h3> <p>这是一种简单而强大的技术，它关注的是用文档记载（并约定）软件模块的权利与责任，以确保程序正确性。</p> <p>用文档记载这样的声明，并进行校验，是按合约设计（简称DBC）的核心所在。</p> <p>使用DBC的最大好处也许是它迫使需求与保证的问题走到前台来。在设计时简单地列举输入域的范围是什么、边界条件是什么、例程允诺交付什么——或者，更重要的，它不允诺交付什么——是向着编写更好的软件的一次飞跃。</p> <h3 id="死程序不说谎"><a href="#死程序不说谎" class="header-anchor">#</a> 死程序不说谎</h3> <p>所有的错误都能为你提供信息。注重实效的程序员告诉自己，如果有一个错误，就说明非常、非常糟糕的事情已经发生了。</p> <p>当你的代码发现，某件被认为不可能发生的事情已经发生时，你的程序就不再有存活能力。从此时开始，它所做的任何事情都会变得可疑，所以要尽快终止它。死程序带来的危害通常比有疾患的程序要小得多。</p> <h2 id="第5章-弯曲或折断"><a href="#第5章-弯曲或折断" class="header-anchor">#</a> 第5章 弯曲或折断</h2> <h3 id="解耦与得墨忒耳法则"><a href="#解耦与得墨忒耳法则" class="header-anchor">#</a> 解耦与得墨忒耳法则</h3> <p>把你的代码组织成最小组织单位（模块），并限制它们之间的交互。如果随后出于折中必须替换某个模块，其他模块仍能够继续工作。</p> <p>有许多不必要的依赖关系的系统非常难以维护（而且很昂贵），往往高度地不稳定。为了使依赖关系保持最少，我们将使用得墨忒耳法则设计我们的方法和函数。</p> <p>函数的得墨忒耳法则试图使任何给定程序中的模块之间的耦合减至最少。</p> <p>使用得墨忒耳法则将使你的代码适应性更好、更健壮，但也有代价：作为“总承包人”，你的模块必须直接委托并管理全部子承包人，而不牵涉你的模块的客户。在实践中，这意味着你将会编写大量包装方法，它们只是把请求转发给被委托者。这些包装方法既会带来运行时代价，也会带来空间开销，在有些应用中，这可能会有重大影响。</p> <p>与任何技术一样，你必须平衡你的特定应用的各种正面因素和负面因素。通过反转得墨忒耳法则，使若干模块紧密耦合，你可以获得重大的性能改进。只要对于那些被耦合在一起的模块而言，这是众所周知的和可以接受的，你的设计就没有问题。</p> <h3 id="时间耦合"><a href="#时间耦合" class="header-anchor">#</a> 时间耦合</h3> <p>时间有两个方面对我们很重要：并发（事情在同一时间发生）和次序（事情在时间中的相对位置）。</p> <p>我们需要容许并发，并考虑解除任何时间或次序上的依赖。这样做，我们可以获得灵活性，并减少许多开发领域中的任何基于时间的依赖：工作流分析、架构、设计、还有部署。</p> <p>在许多项目中，我们需要把用户的工作流当作需求分析的一部分来进行建模和分析。我们想要找出在同一时间可能发生什么，以及什么必须以严格的次序发生。要做到这一点，一种途径是使用像UML活动图这样的表示法来捕捉他们对工作流的描述。</p> <p>编写线性代码，我们很容易做出一些假定，把我们引向不整洁的编程。但并发迫使你更仔细地对事情进行思考——这不再是你一个人的舞会。因为事情现在可能会在“同一时间”发生，你可能会突然看到某些基于时间的依赖关系。</p> <p>如果我们在设计时就考虑了并发，到时我们就可以更容易地满足可伸缩性或性能需求——即使那样的时候不会到来，我们也仍然拥有更整洁的设计带来的好处。</p> <h2 id="第6章-当你编码时"><a href="#第6章-当你编码时" class="header-anchor">#</a> 第6章 当你编码时</h2> <h3 id="靠巧合编程"><a href="#靠巧合编程" class="header-anchor">#</a> 靠巧合编程</h3> <p>有时我们可能会依靠巧合。会把“幸运的巧合”与有目的的计划混为一谈。</p> <p>面对这种“幸运的巧合”，我们在编程中可以考虑以下几条理由：</p> <ul><li>它也许不是真的能工作——它也许只是看来起能工作；</li> <li>你依靠的边界条件也许只是个偶然，在不同的情形下，它的表现可能就会不同；</li> <li>没有记入文档的行为可能会随着库的下一次发布而变化；</li> <li>多余的和不必要的调用会使你的代码变慢；</li> <li>多余的调用还会增加引入它们自己的Bug的风险。</li></ul> <p>巧合可以在所有层面上让人误入歧途——从生成需求直到测试。特别是测试，充满了虚假的因果关系和巧合的输出。</p> <p>在所有层面上，人们的头脑中都带着许多假定在工作——但这些假定很少被记录文档，而且在不同的开发者之间常常是冲突的。并非以明确的事实为基础的假定是所有项目的祸害。</p> <h3 id="如何深思熟虑地编程"><a href="#如何深思熟虑地编程" class="header-anchor">#</a> 如何深思熟虑地编程</h3> <ul><li><p>总是意识到你在做什么。不要让事情慢慢失去控制，直到最后爆发，就像“温水煮青蛙”一样。</p></li> <li><p>不要盲目地编程。试图构建你不完全理解的应用，或是使用你不熟悉的技术，就是希望自己被巧合误导。</p></li> <li><p>按照计划行事。不管计划是在你的头脑里，还是在生成的书面文件上。</p></li> <li><p>依靠可靠的事物。不要依靠巧合或假定。如果无法说出各种特定情形的区别，那就假定是最坏的。</p></li> <li><p>为你的假定建立文档。这有助于澄清你头脑里的假定，并且有助于把它们传达给别人。</p></li> <li><p>不要只是测试你的代码，还要测试你的假定。</p></li> <li><p>为你的工作划分优先级。把时间花在重要的方面。</p></li> <li><p>不要让已有的代码支配将来的代码。如果不再适用，所有的代码都可别替换。不要让你已经做完的事情约束你下一步要做的事情——准备好进行重构。</p></li></ul> <h3 id="重构"><a href="#重构" class="header-anchor">#</a> 重构</h3> <p>当代码具有以下的这些特征时，你都应该考虑重构代码：</p> <ul><li><strong>重复</strong>——你发现了对DRY原则的违反。</li> <li><strong>非正交的设计</strong>——你发现有些代码或设计可以变得更为正交。</li> <li><strong>过时的知识</strong>——事情变了，需求转移了，你对问题的了解更深了，代码需要跟上这些变化。</li> <li><strong>性能</strong>——为改善性能，你需要把功能从系统的一个区域移动到另一个区域。</li></ul> <p>发现了问题，如果现在没能进行重构，沿途修正问题将需要投入多得多的时间，那时将需要考虑更多的依赖关系。</p> <p>追踪需要重构的事物。如果你不能立刻重构某样东西，就一定要把它列入计划，确保受到影响的代码的使用者知道该代码计划要重构，以及这可能会怎么影响他们。</p> <p>重构是一项需要慎重、深思熟虑、小心进行的活动。关于怎样进行利大于弊的重构，可以遵循以下几点提示：</p> <ul><li>在开始重构之前，确保你拥有良好的测试。尽可能经常运行这些测试。这样，如果你的改动破坏了任何东西，你就能快速知道。</li> <li>采用短小、深思熟虑的步骤。重构常常涉及到进行许多局部改动，继而产生更大规模的改动。如果你使你的步骤保持短小，并在每个步骤之后进行测试，你将能够避免长时间的调试。</li></ul> <h2 id="第7章-在项目开始之前"><a href="#第7章-在项目开始之前" class="header-anchor">#</a> 第7章 在项目开始之前</h2> <h3 id="需求之坑"><a href="#需求之坑" class="header-anchor">#</a> 需求之坑</h3> <p>需求不是靠搜集得来的，他们很少存在于表面，通常都深深的埋藏在层层假定和误解的下面，我们需要不断地挖掘它们。</p> <p><strong>挖掘需求</strong></p> <p>在挖掘过程中，如何才能识别出真实的需求？答案既简单有复杂。</p> <p>简单的回答是，需求是对需要完成的某件事情的陈述。但是，极少有需求能陈述的清晰明了，这也正是需求分析很复杂的原因。</p> <p>找出用户为何要做特定事情的原因、而不只是他们目前做这件事情的方式，这很重要。到最后，你的开发必须解决他们的商业问题，而不只是满足他们陈述的需求。用文档记载需求背后的原因将在每天进行实现决策时给你的团队带来无价的信息。</p> <p>有一种能深入了解用户需求、却未得到足够利用的技术：成为用户（与用户一同工作，像用户一样思考）。</p> <p>开采需求的过程中也是开始与用户群建立和谐关系、了解他们对你正在构建的系统的期许和希望的时候。</p> <p><strong>建立需求文档</strong></p> <p>从用户那儿探求到的真是需求，和你遇到的一些合适的、描述应用需要做什么的情境，把他们写下来，并发布给项目参与的每个人，用作谈论的基础文档。</p> <p>活用UML用例图捕捉工作流，来为复杂的信息建立文档。但不要做任何方法的奴隶，只要是能对与用户交流需求的好方法，都可以加以利用。</p> <p>制作需求文档时的一大危险是太过具体。好的需求文档会保持抽象。在涉及需求的地方，最简单的，能够准确地反应商业需要的陈述是最好的。</p> <p>需求不是架构。需求不是设计，也不是用户界面。需求是需要。</p> <p>把项目需求文档发布到内部的网站上，以方便所有参与者的访问。通过把需求文档制作成超文本文档，我们可以更好的满足不同听众的需要——我们可以给每个读者他们想要的东西。</p> <h3 id="等你准备好"><a href="#等你准备好" class="header-anchor">#</a> 等你准备好</h3> <p>作为开发者，当我们面对一件任务时，如果反复感觉到疑虑，或是体验到某种勉强，要注意它。你可能无法准确地指出问题所在，但请给它时间，你的疑虑很可能会结晶成某种更坚实的东西，某种你可以处理的东西。</p> <p>面对这种疑虑，我们可以采用的一种行之有效的技术是开始构建原型，选择一个你觉得会有困难的地方，开始进行某种“概念验证”。</p> <p>在验证的过程中，可能会发现两种情况：</p> <ul><li>一种情况是，开始后不久，你可能就觉得自己在浪费时间，这种情况就很好的表明，你最初的疑虑只是一种拖延。所以放弃原型，回到真正的开发中。</li> <li>另一种情况是，随着原型取得进展，你可能会在某个时刻得到启示，突然意识到有些基本的前提错了。不仅如此，你还将清楚的看到可以怎样纠正错误。这样你就为你自己或你的团队节省了可观、本来会被浪费的时间和努力。</li></ul> <h2 id="第8章-注重实效的项目"><a href="#第8章-注重实效的项目" class="header-anchor">#</a> 第8章 注重实效的项目</h2> <h3 id="注重实效的团队"><a href="#注重实效的团队" class="header-anchor">#</a> 注重实效的团队</h3> <p>团队作为一个整体，不应该容忍破窗户——那些小小的、无人修正的不完美。团队必须为产品的质量负责。</p> <p>即使是目的最明确的团队对项目中的重大改动也会遗忘。要确保每个人都能主动的监控环境的变化，对新需求进行持续的度量与关注。</p> <p>团队中的开发者必须相互交流，看上去沉默寡言的项目团队是最糟糕的团队。而杰出的项目团队有着截然不同的个性。人们希望与他们开会，因为他们知道自己将看到准备良好、会让每个人都感到愉悦的演出。他们制作的文档新鲜、准确、一致。团队用一个声音说话。他们甚至还可能有幽默感。</p> <p>确保一致和准确的一种很好的方式是使团队所做的每件事情自动化。</p> <p>团队是由个体组成的。让每个成员都能以他们自己的方式闪亮。给他们足够的空间，以支持他们，并确保项目的交付能够符合需求。</p> <h3 id="极大的期望"><a href="#极大的期望" class="header-anchor">#</a> 极大的期望</h3> <p>在现实中，项目的成功是由它在多大程度上满足了用户的期望来衡量的。不符合用户预期的项目注定是失败的，不管交付的产品在绝对的意义上有多好。</p> <p>所以我们要做到<strong>温和地超出用户的期望</strong>，做到这点需要做一些工作：</p> <p>保持与用户交流，与你的用户一同工作，以使他们正确地理解你将要交付的产品。并且要在整个开发过程中进行这样的交流。决不要忘了你的应用要解决的商业问题。</p> <p>如果你和用户紧密协作，分享他们的期望，并同他们交流你正在做的事情，那么当项目交付时，就不会发生多少让人吃惊的事情了。</p> <p>要设法让你的用户惊讶。请注意，不是惊吓他们，而是要让他们高兴。给他们的东西要比他们期望的多一点。给系统增加某种面向用户的特性所需的一点额外努力将一次又一次在商誉上带来回报。</p></div></div> <!----> <div class="page-edit"><!----> <div class="tags"><a href="/brennan-wu-blog/tags/?tag=%E7%A8%8B%E5%BA%8F%E5%91%98" title="标签">#程序员</a></div> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">2023/04/26, 07:29:08</span></div></div> <div class="page-nav-wapper"><div class="page-nav-centre-wrap"><a href="/brennan-wu-blog/pages/2ffcfe/" class="page-nav-centre page-nav-centre-prev"><div class="tooltip">《技术领导力：程序员如何才能带团队》读书笔记</div></a> <a href="/brennan-wu-blog/pages/c002a8/" class="page-nav-centre page-nav-centre-next"><div class="tooltip">《从技术走向管理：李元芳履职记》读书笔记</div></a></div> <div class="page-nav"><p class="inner"><span class="prev">
        ←
        <a href="/brennan-wu-blog/pages/2ffcfe/" class="prev">《技术领导力：程序员如何才能带团队》读书笔记</a></span> <span class="next"><a href="/brennan-wu-blog/pages/c002a8/">《从技术走向管理：李元芳履职记》读书笔记</a>→
      </span></p></div></div></div> <div class="article-list"><div class="article-title"><a href="/brennan-wu-blog/archives/" class="iconfont icon-bi">最近更新</a></div> <div class="article-wrapper"><dl><dd>01</dd> <dt><a href="/brennan-wu-blog/pages/8a0173/"><div>
            职业路线：前端工程师的晋升逻辑到底是什么
            <!----></div></a> <span class="date">05-02</span></dt></dl><dl><dd>02</dd> <dt><a href="/brennan-wu-blog/pages/c002a8/"><div>
            《从技术走向管理：李元芳履职记》读书笔记
            <!----></div></a> <span class="date">04-15</span></dt></dl><dl><dd>03</dd> <dt><a href="/brennan-wu-blog/pages/2641af/"><div>
            解读《真希望我父母读过这本书》
            <!----></div></a> <span class="date">11-28</span></dt></dl> <dl><dd></dd> <dt><a href="/brennan-wu-blog/archives/" class="more">更多文章&gt;</a></dt></dl></div></div></main></div> <div class="footer"><div class="icons"><a href="mailto:985979261@qq.com" title="发邮件" target="_blank" class="iconfont icon-juchangxinxiang"></a><a href="https://github.com/wyd112821" title="GitHub" target="_blank" class="iconfont icon-github"></a><a href="https://gitee.com/wuyadong112821" title="gitee" target="_blank" class="iconfont icon-gitee"></a></div> 
  Theme by
  <a href="https://github.com/xugaoyi/vuepress-theme-vdoing" target="_blank" title="本站主题">Vdoing</a> 
    | Copyright © 2022-2023
    <span>Brennan Wu | <a href="https://github.com/xugaoyi/vuepress-theme-vdoing/blob/master/LICENSE" target="_blank">MIT License</a></span></div> <div class="buttons"><div title="返回顶部" class="button blur go-to-top iconfont icon-262" style="display:none;"></div> <div title="去评论" class="button blur go-to-comment iconfont icon-pinglun" style="display:none;"></div> <div title="主题模式" class="button blur theme-mode-but iconfont icon-43_zhuti"><ul class="select-box" style="display:none;"><li class="iconfont icon-zidong">
          跟随系统
        </li><li class="iconfont icon-rijianmoshi">
          浅色模式
        </li><li class="iconfont icon-yejianmoshi">
          深色模式
        </li><li class="iconfont icon-yuedu">
          阅读模式
        </li></ul></div></div> <!----> <!----> <!----></div><div class="global-ui"></div></div>
    <script src="/brennan-wu-blog/assets/js/app.422e2e24.js" defer></script><script src="/brennan-wu-blog/assets/js/2.372f0770.js" defer></script><script src="/brennan-wu-blog/assets/js/3.22a0f36b.js" defer></script><script src="/brennan-wu-blog/assets/js/28.d5292c46.js" defer></script>
  </body>
</html>
